package org.dreamwork.jasmine2.web.controls;

import org.dreamwork.jasmine2.engine.*;
import org.dreamwork.jasmine2.events.*;
import org.dreamwork.jasmine2.web.IWebControl;
import org.dreamwork.util.NameValueCollection;
import org.dreamwork.peony.DataBinder;

import java.io.IOException;
import java.io.PrintWriter;

/**
 * Created by IntelliJ IDEA.
 * User: seth
 * Date: 2009-2-2
 * Time: 16:53:11
 */
public class TextBox extends WebControl implements IPostbackHandler, IValidatable, IChangable {
    private String text;
    private boolean multiline = false;

    private ValidatableDelegate validateDelegate = new ValidatableDelegate ();
    private ChangableDelegate changeDelegate = new ChangableDelegate ();

    public void setAttribute (String attrName, String attrValue) {
        if ("value".equalsIgnoreCase (attrName) || "text".equalsIgnoreCase (attrName))
            setText (attrValue);
        else
            super.setAttribute (attrName, attrValue);
    }

    // life circle
    public void init () {
        super.init ();
        if (multiline)
            htmlTagName = "textarea";
        else {
            htmlTagName = "input";
//            attrs.setProperty ("type", "text");
        }

        if (runAtServer && autoPostback) {
            page.registerClientScriptBlock (InternalJS.class, InternalJS.ON_CLICK_JS);
            attrs.setProperty ("onchange", "__client_stub (this, 'change', 'text')");
        }

        attrs.setProperty ("name", id);
    }

    public String getText () {
        if (text != null) return text;
        text = attrs.getProperty ("text");
        if (text != null) return text;
        return text = (String) oldAttributes.get ("text");
    }

    public void setText (String text) {
        this.text = text;
        if (viewStateEnabled)
            stateManager.put ("text", text);
    }

    public boolean isMultiline () {
        return multiline;
    }

    public void setMultiline (boolean multiline) {
        this.multiline = multiline;
    }

    public void postbackData (NameValueCollection props) {
        String value = props.getValue (getName ());
        if (value != null) setText (value);
    }
/*

    protected ViewStateManager getViewState () {
        return stateManager;
    }
*/

    public void onPrerender (IWebControl sender, HttpContext context) throws EventException {
        if (!multiline && getText () != null) attrs.setProperty ("value", text);
    }

    public void render (PrintWriter writer) throws IOException, EventException {
        super.render (writer);
        if (multiline) {
            writer.print (text == null ? "" : text);
            writer.println ("</" + htmlTagName + ">");
        }
    }

    protected void beginTag (PrintWriter writer) throws IOException {
        if (!multiline)
            super.beginTag (writer);
        else {
            writer.print ("<" + htmlTagName);
            for (Object o : attrs.keySet ()) {
                String attrName = (String) o;
                if (isIgnoredAttribute (attrName)) continue;
                String value = attrs.getProperty (attrName);
                writer.print (" " + attrName + "=\"" + value + "\"");
            }
            writer.print (">");
        }
    }

    public void onDataBind (Object sender) throws EventException {
        if (dataSource != null || valueField != null) {
            Object value = DataBinder.eval (dataSource, valueField);
            setText (value == null ? "" : value.toString ());
        }
    }

    protected void loadViewState (Object savedState) throws IOException {
        stateManager.loadViewState (savedState);
        String text = (String) stateManager.get ("text");
        if (text != null)
            oldAttributes.put ("text", text);
    }

    public void addChangeListener (IChangeListener listener) {
        changeDelegate.addChangeListener (listener);
    }

    public void removeChangeListener (IChangeListener listener) {
        changeDelegate.removeChangeListener (listener);
    }

    public void fireChange (IWebControl sender, String attrName, Object oldValue, Object newValue) throws EventException {
        changeDelegate.fireChange (sender, attrName, oldValue, newValue);
    }

    public IChangeListener[] getChangeListeners () {
        return changeDelegate.getChangeListeners ();
    }

    public void addValidateListener (IValidateListener listener) {
        validateDelegate.addValidateListener (listener);
    }

    public void removeValidateListener (IValidateListener listener) {
        validateDelegate.removeValidateListener (listener);
    }

    public IValidateListener[] getValidateListners () {
        return validateDelegate.getValidateListners ();
    }

    public boolean fireValidateListeners (IWebControl sender) {
        return validateDelegate.fireValidateListeners (sender);
    }
}